package  
{
	import Base.Net.NetSocket;
	
	import Common.GameDefine;
	import Common.GameNetEvent;
	import Common.GameNetManager;
	
	import Common.MapDirection;
	import map.MapGrid;
	import map.MapPos;
	import map.PathFinder;
	import Common.GameAction;
	
	
	
	
	/**
	 * ...
	 * @author ...
	 */
	public class GameCreatureMove
	{
		public var mapPos:MapPos = null;
		
		public var movePos:MapGrid = null;
		public var movePath:Array = null;
		
		public var movePathBuffer:Boolean = false;
		public var movePathBackup:MapGrid = null;
		
		
		public var isDirectionBuffer:Boolean = false;
		public var directionBuffer:int = MapDirection.DIRECTCOUNT;
		
		public var moveDirection:int = MapDirection.SOUTHWEST;
		
		private var owner:Object = null;
		
		private var mapGridLast:MapGrid = null;
		
		
		public function GameCreatureMove() 
		{
			
		}
		
		public function init( owner:Object ):void
		{
			this.owner = owner;
			
			mapPos = new MapPos();
			mapPos.init();
			
			movePos = new MapGrid();
			movePath = new Array();
			movePathBackup = new MapGrid();
			
			mapGridLast = new MapGrid();
		}
		
		public function release():void
		{
			owner = null;
			
			mapPos.release();
			mapPos = null;
			
			movePos = null;
			movePath = null;
			movePathBackup = null;
			mapGridLast = null;
		}
		
		public function endMoving():void
		{
			if ( movePath.length )
			{
				mapPos.mapGrid.setValue( movePath[ movePath.length - 1 ].x , movePath[ movePath.length - 1 ].y );
				
				while( movePath.length )
				{
					movePath.shift();
				}
			}
			
			owner.state = GameCeatureState.STAND;
			
			if ( isDirectionBuffer ) 
			{
				isDirectionBuffer = false;
				moveDirection = directionBuffer;
			}
			
			movePathBuffer = false;
			
			
			owner.setAction( GameAction.STAND );
		}
		
		
		public function startMoving():void
		{
			owner.state = GameCeatureState.MOVE;
			
			updateDirection();
			
			owner.setAction( GameAction.MOVE );
		}
		
		
		private function updateDirection():void
		{
			if ( movePathBuffer )
			{
				if ( mapPos.mapGrid.equals( movePathBackup ) )
				{
					endMoving();
					return;
				}
				
				movePath = PathFinder.instance.findPath( mapPos.mapGrid.x , mapPos.mapGrid.y , movePathBackup.x , movePathBackup.y ).concat();
				movePathBuffer = false;
				
				sendMoveMsg();
				movePath.shift();
				
				//var start:Boolean = false;
				
				if ( owner.team && owner.team.leader == owner )
				{
					for ( var i:int = 1 ; i < owner.team.members.length ; i++ )
					{
						owner.team.members[i].moveHandler.movePath = owner.team.members[i-1].moveHandler.movePath.concat();
						
						//if ( owner.team.members[i].moveHandler.movePath.length && owner.team.members[i].moveHandler.movePath[0] != owner.team.members[i-1].moveHandler.movePath[0] )
						//{
						//	
						//	owner.team.members[i].moveHandler.movePath.unshift( owner.team.members[i-1].moveHandler.movePos.clone() );
						//}
						
						owner.team.members[i].moveHandler.movePath.pop();
						owner.team.members[i].moveHandler.movePath.unshift( owner.team.members[i-1].moveHandler.mapPos.mapGrid.clone() );
						
						if ( owner.team.members[i].state != GameCeatureState.MOVE )
						{
							owner.team.members[i].moveHandler.startMoving();
						}
						
						
						//trace( moveHandler.movePath );
						//trace( team.members[i].moveHandler.movePath );
					}
				}
			}
			
			if ( !movePath.length )
			{
				endMoving();
				return;
			}
			
			//trace( movePath );
			
			movePos = movePath[0];
			movePath.shift();
			
//			owner.moveBuffer.push( movePos );
			
//			if ( owner.moveBuffer.length > 4 )
//			{
//				owner.moveBuffer.shift();
//			}
			
//			trace( owner.moveBuffer );
			
			var lastDirection:int = moveDirection;
			moveDirection = MapPos.GetDirect( movePos , mapPos.mapGrid );
			
			if ( moveDirection == MapDirection.DIRECTCOUNT )
			{
				moveDirection = lastDirection;
			}
			
			mapPos.startMove( movePos );
			
			if ( lastDirection != moveDirection ) 
			{
				owner.setAction( GameAction.MOVE );
			}
		}
		
		public function update( delay:Number ):void
		{
			if ( owner.state != GameCeatureState.MOVE )
			{
				return;
			}
			
			mapPos.move( delay );
			
			owner.move();
			
			if ( !mapPos.isMoving )
			{
				updateDirection();
			}
			
			if ( !mapPos.mapGrid.equals( mapGridLast ) )
			{
				GameCreatureManager.instance.updatePlayerScene( owner as GamePlayer );
			}
			
			mapGridLast.x = mapPos.mapGrid.x;
			mapGridLast.y = mapPos.mapGrid.y;
		}
		
		public function sendMoveMsg():void
		{
			if ( movePath.length == 0 )
			{
				return;
			}
			if ( movePath.length > GameDefine.MAX_MOVE_PATH )
				movePath.length = GameDefine.MAX_MOVE_PATH;
			
			var netSocket:NetSocket = GameNetManager.instance.MainNetSocket;
			
			netSocket.writeShort( 16 + movePath.length * 4 );
			netSocket.writeShort( GameNetEvent.SEND_MOVE_ID );
			
			netSocket.writeInt( owner.ID );
			netSocket.writeInt( mapPos.mapID );
			netSocket.writeInt( movePath.length );
			
			for (var i:int = 0; i < movePath.length ; i++) 
			{
				netSocket.writeShort( movePath[i].x );
				netSocket.writeShort( movePath[i].y );
			}
			
			netSocket.Send();
		}
	}

}